package com.common.util;

import cn.hutool.core.util.StrUtil;
import com.common.util.groovy.GroovyParser;
import groovy.lang.Binding;

import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>groovy脚本</p>
 */
public class GroovyUtils {

    /** @{}匹配*/
    private static final Pattern p = Pattern.compile("\\@\\{.*?\\}", Pattern.MULTILINE);

    /**
     * 动态执行groovy函数
     * @param code              groovy代码体
     * @param args              参数
     * @return                  执行结果
     */
    public static Object invoke(String code, Map args) {
        try {
            if (StrUtil.isBlank(code)) {
                throw new RuntimeException("执行groovy代码块不能为空");
            }

            //直接打3.25
            if (StrUtil.containsIgnoreCase(code, "system.exit")) {
                throw new RuntimeException("不能包含System.exit");
            }

            Binding binding = new Binding();
            if(null != args && args.size() > 0) {
                for (Object parameterName : args.keySet()) {
                    binding.setProperty(parameterName + "", args.get(parameterName));
                }
            }
            Object rs = GroovyParser.parse(code, binding);
            return rs;
        } catch (Exception e) {
            throw new RuntimeException("执行方法失败[" + e.getMessage() + "]", e);
        }
    }

    /**
     *
     * @param executeSQL
     * @param groovyVariablesOfRule
     * @return
     */
    public static String eval(String executeSQL, Map groovyVariablesOfRule) {
        Matcher m = p.matcher(executeSQL);
        StringBuffer sb = new StringBuffer();
        while (m.find()) {
            String propertyName = m.group().replace("@{", "").replace("}", "");
            m.appendReplacement(sb,
                groovyVariablesOfRule.get(StrUtil.trimToEmpty(propertyName)) + "");
        }
        m.appendTail(sb);
        return sb.length() == 0 ? executeSQL : sb.toString();
    }

    /**
     * 将脚本中的@{}引用去掉
     * @param script
     * @return
     */
    public static String transferVarsReferenceByColumnName(String script) {
        if (StrUtil.isBlank(script)) {
            return script;
        }
        Matcher m = p.matcher(script);
        StringBuffer sb = new StringBuffer();
        while (m.find()) {
            String propertyName = m.group().replace("@{", "").replace("}", "");
            m.appendReplacement(sb, StrUtil.trimToEmpty(propertyName));
        }
        m.appendTail(sb);
        return sb.length() == 0 ? script : sb.toString();
    }
}
